home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 7 / FM Towns Free Software Collection 7.iso / taropyon / zmodem / src / rbsb.c < prev    next >
C/C++ Source or Header  |  1993-11-30  |  10KB  |  460 lines

  1. /*
  2.  * Rev 5-09-89 This file contains Unix specific code for setting terminal modes,
  3.  * very little is specific to ZMODEM or YMODEM per se (that code is in sz.c
  4.  * and rz.c).  The CRC-16 routines used by XMODEM, YMODEM, and ZMODEM are
  5.  * also in this file, a fast table driven macro version
  6.  *
  7.  * V7/BSD HACKERS:    SEE NOTES UNDER mode(2) !!!
  8.  *
  9.  * This file is #included so the main file can set parameters such as HOWMANY.
  10.  * See the main files (rz.c/sz.c) for compile instructions. */
  11.  
  12. #ifdef V7
  13. #    include <sys/types.h>
  14. #    include <sys/stat.h>
  15. #    define STAT
  16. #    include <sgtty.h>
  17. #    define OS "V7/BSD"
  18. #    define ROPMODE "r"
  19. #    ifdef LLITOUT
  20. long        Locmode;            /* Saved "local mode" for 4.x BSD "new
  21.                                  * driver" */
  22. long        Locbit = LLITOUT;    /* Bit SUPPOSED to disable output
  23.                                  * translations */
  24. #        include <strings.h>
  25. #    endif
  26. #endif
  27.  
  28. #ifdef    __TOWNS__
  29. #    define OS "TownsOS"
  30. #    define ROPMODE "rb"
  31. #    define MODE2OK
  32. #else
  33. #    ifndef OS
  34. #        ifndef USG
  35. #            define USG
  36. #        endif
  37. #    endif
  38.  
  39. #    ifdef USG
  40. #        include <sys/types.h>
  41. #        include <sys/stat.h>
  42. #        define STAT
  43. #        define OS "SYS III/V"
  44. #        define ROPMODE "r"
  45. #        define MODE2OK
  46. #        include <string.h>
  47. #    endif
  48. #endif
  49.  
  50. #ifdef T6K
  51. #    include <sys/ioctl.h>        /* JPRadley: for the Tandy 6000 */
  52. #endif
  53.  
  54. #if HOWMANY  > 255
  55. Howmany must be 255 or less
  56. #endif
  57.  
  58. /*
  59.  * return 1 iff stdout and stderr are different devices indicating this
  60.  * program operating with a modem on a different line
  61.  */
  62. int         Fromcu;             /* Were called from cu or yam */
  63.  
  64. void    from_cu(void)
  65. {
  66. #ifdef    __TOWNS__
  67.     Fromcu = 1;
  68. #else
  69.     struct stat a, b;
  70.  
  71.     fstat(1, &a);
  72.     fstat(2, &b);
  73.     Fromcu = a.st_rdev != b.st_rdev;
  74.     return;
  75. #endif
  76. }
  77.  
  78. void    cucheck(void)
  79. {
  80.     if ( Fromcu )
  81.         USR_fprintf(stderr, "Please read the manual page BUGS chapter!\r\n");
  82. }
  83.  
  84.  
  85. #ifndef    __TOWNS__
  86. struct
  87. {
  88.     unsigned    baudr;
  89.     int         speedcode;
  90. } speeds[] =
  91. {
  92.       110, B110,
  93.       300, B300,
  94.       600, B600,
  95.      1200, B1200,
  96.      2400, B2400,
  97.      4800, B4800,
  98.      9600, B9600,
  99.     19200, EXTA,
  100.     38400, EXTB,
  101.     0,
  102. };
  103. #endif
  104.  
  105. int         Twostop;            /* Use two stop bits */
  106.  
  107. /*
  108.  * The following uses an external rdchk() routine if available, otherwise
  109.  * defines the function for BSD or fakes it for SYSV.
  110.  */
  111.  
  112. #ifdef    __TOWNS__
  113. #    ifdef    READCHECK
  114.     int        rdchk(int f)
  115.     {
  116.         if ( RS_chk(RsPort) > 0 )
  117.             return (1);
  118.         else
  119.             return (0);
  120.     }
  121. #    endif
  122. #endif
  123.  
  124. #ifndef READCHECK
  125. #ifdef FIONREAD
  126. #define READCHECK
  127. /*
  128.  * Return non 0 iff something to read from io descriptor f
  129.  */
  130. rdchk(f)
  131. {
  132.     static long lf;
  133.  
  134.     ioctl(f, FIONREAD, &lf);
  135.     return ((int) lf);
  136. }
  137.  
  138. #else                            /* FIONREAD */
  139.  
  140. #ifdef SV
  141. #define READCHECK
  142. #include <fcntl.h>
  143.  
  144. int         checked = 0;
  145. /*
  146.  * Nonblocking I/O is a bit different in System V, Release 2 Note: this rdchk
  147.  * vsn throws away a byte, OK for ZMODEM sender because protocol design
  148.  * anticipates this problem.
  149.  */
  150. #define EATSIT
  151. rdchk(f)
  152. {
  153.     int         lf, savestat;
  154.     static char bchecked;
  155.  
  156.     savestat = fcntl(f, F_GETFL);
  157.     fcntl(f, F_SETFL, savestat | O_NDELAY);
  158.     lf = read(f, &bchecked, 1);
  159.     fcntl(f, F_SETFL, savestat);
  160.     checked = bchecked & 0377;    /* force unsigned byte */
  161.     return (lf);
  162. }
  163. #endif
  164. #endif
  165. #endif
  166.  
  167.  
  168. static unsigned    getspeed(int code)
  169. {
  170. #ifdef    __TOWNS__
  171.     switch ( code )
  172.     {
  173.         case RSBAUD_300:    return (300);
  174.         case RSBAUD_600:    return (600);
  175.         case RSBAUD_1200:    return (1200);
  176.         case RSBAUD_2400:    return (2400);
  177.         case RSBAUD_4800:    return (4800);
  178.         case RSBAUD_9600:    return (9600);
  179.         case RSBAUD_19200:    return (19200);
  180.         default:            return (9600);
  181.     }
  182. #else
  183.     register int    n;
  184.  
  185.     for ( n = 0; speeds[n].baudr; ++n )
  186.         if (speeds[n].speedcode == code)
  187.             return speeds[n].baudr;
  188.     return 38400;                /* Assume fifo if ioctl failed */
  189. #endif
  190. }
  191.  
  192.  
  193. #ifdef    __TOWNS__
  194.     static int    OldMd, OldBaud;
  195.     static int    SavePort = -1;
  196. #else
  197. #ifdef ICANON
  198. struct termio oldtty, tty;
  199. #else
  200. struct sgttyb oldtty, tty;
  201. struct tchars oldtch, tch;
  202. #endif
  203. #endif
  204.  
  205. #ifdef    __TOWNS__
  206. static    int        rsOpenChk(int port)
  207. {
  208.     extern    int        RsBaud;
  209.     extern    int        RsMd;
  210.  
  211.     if ( RsCtrl[port].use == 0 )
  212.     {
  213.         RS_open( port );
  214.         if ( RsBaud >= 0 || RsMd >= 0 )
  215.         {
  216.             int        baud;
  217.             int        md;
  218.  
  219.             baud = ( RsBaud >= 0 ) ? RsBaud : RsCtrl[RsPort].rsb->baud;
  220.             md   = ( RsMd >= 0 ) ? RsMd : RsCtrl[RsPort].rsb->mode;
  221.             RS_reopen(RsPort, md, baud );
  222.         }
  223.     }
  224.     return (1); /* OK */
  225. }
  226. #endif
  227.  
  228. /*
  229.  * mode(n)
  230.  *   3: save old tty stat, set raw mode with flow control
  231.  *   2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g
  232.  *   1: save old tty stat, set raw mode
  233.  *   0: restore original tty mode
  234.  */
  235. static    int        mode(int n)
  236. {
  237.     static int    did0 = FALSE;
  238.  
  239.     vfile("mode:%d", n);
  240.     switch (n)
  241.     {
  242. #ifdef    __TOWNS__
  243.         case 2:            /* set XON/XOFF for sb/sz with ZMODEM or YMODEM-g */
  244.             if (!did0)
  245.             {
  246.                 if ( rsOpenChk( RsPort ) )
  247.                 {
  248.                     OldMd   = RsCtrl[RsPort].rsb->mode;
  249.                     OldBaud = RsCtrl[RsPort].rsb->baud;
  250.                 } else
  251.                     return ERROR;
  252.             }
  253.             {
  254.                 int        md, baud;
  255.                 md   = OldMd | RSMD_XCTRL_ON;
  256.                 RS_reopen(RsPort, md, OldBaud);    /* XCTRL ON */
  257.             }
  258.             RSB_CTRL(RsPort,0x22);
  259.             did0 = TRUE;
  260.             return OK;
  261.  
  262.         case 1:    /* save old tty stat, set raw mode */
  263.         case 3:    /* save old tty stat, set raw mode with flow control */
  264.             if (!did0)
  265.             {    /* save */
  266.                 if ( rsOpenChk( RsPort ) )
  267.                 {
  268.                     OldMd   = RsCtrl[RsPort].rsb->mode;
  269.                     OldBaud = RsCtrl[RsPort].rsb->baud;
  270.                 } else
  271.                     return ERROR;
  272.             }
  273.             {
  274.                 int        md, baud;
  275.  
  276.                 md   = OldMd & (~RSMD_XCTRL_ON);    /* XCTRL OFF */
  277.                 RS_reopen(RsPort, md, OldBaud);
  278.                 RSB_CTRL(RsPort,0x22);
  279.             }
  280.             /*Effbaud =*/ Baudrate = getspeed(OldBaud);
  281.             did0 = TRUE;
  282.             return OK;
  283.  
  284.         case 0: /* restore original tty mode */
  285.             if (!did0)
  286.                 return ERROR;
  287.             RS_reopen(RsPort, OldMd, OldBaud);
  288.             did0 = FALSE;
  289.             return OK;
  290.  
  291.         default:
  292.             return ERROR;
  293. #else
  294. #ifdef USG
  295.         case 2:         /* Un-raw mode used by sz, sb when -g
  296.                                  * detected */
  297.             if (!did0)
  298.                 (void) ioctl(0, TCGETA, &oldtty);
  299.             tty = oldtty;
  300.  
  301.             tty.c_iflag = BRKINT | IXON;
  302.  
  303.             tty.c_oflag = 0;    /* Transparent output */
  304.  
  305.             tty.c_cflag &= ~PARENB;     /* Disable parity */
  306.             tty.c_cflag |= CS8; /* Set character size = 8 */
  307.             if (Twostop)
  308.                 tty.c_cflag |= CSTOPB;    /* Set two stop bits */
  309.  
  310.  
  311. #ifdef READCHECK
  312.             tty.c_lflag = Zmodem ? 0 : ISIG;
  313.             tty.c_cc[VINTR] = Zmodem ? -1 : 030;        /* Interrupt char */
  314. #else
  315.             tty.c_lflag = ISIG;
  316.             tty.c_cc[VINTR] = Zmodem ? 03 : 030;        /* Interrupt char */
  317. #endif
  318.             tty.c_cc[VQUIT] = -1;        /* Quit char */
  319. #ifdef NFGVMIN
  320.             tty.c_cc[VMIN] = 1;
  321. #else
  322.             tty.c_cc[VMIN] = 3; /* This many chars satisfies reads */
  323. #endif
  324.             tty.c_cc[VTIME] = 1;/* or in this many tenths of seconds */
  325.  
  326.             (void) ioctl(0, TCSETAW, &tty);
  327.             did0 = TRUE;
  328.             return OK;
  329.         case 1:
  330.         case 3:
  331.             if (!did0)
  332.                 (void) ioctl(0, TCGETA, &oldtty);
  333.             tty = oldtty;
  334.  
  335.             tty.c_iflag = n == 3 ? (IGNBRK | IXOFF) : IGNBRK;
  336.  
  337.             /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */
  338.             tty.c_lflag &= ~(ECHO | ICANON | ISIG);
  339.  
  340.             tty.c_oflag = 0;    /* Transparent output */
  341.  
  342.             tty.c_cflag &= ~PARENB;     /* Same baud rate, disable parity */
  343.             tty.c_cflag |= CS8; /* Set character size = 8 */
  344.             if (Twostop)
  345.                 tty.c_cflag |= CSTOPB;    /* Set two stop bits */
  346. #ifdef NFGVMIN
  347.             tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
  348. #else
  349.             tty.c_cc[VMIN] = HOWMANY;    /* This many chars satisfies reads */
  350. #endif
  351.             tty.c_cc[VTIME] = 1;/* or in this many tenths of seconds */
  352.             (void) ioctl(0, TCSETAW, &tty);
  353.             did0 = TRUE;
  354.             Effbaud = Baudrate = getspeed(tty.c_cflag & CBAUD);
  355.             return OK;
  356. #endif
  357.  
  358. #ifdef V7
  359.             /*
  360.              * NOTE: this should transmit all 8 bits and at the same time
  361.              * respond to XOFF/XON flow control.  If no FIONREAD or other
  362.              * rdchk() alternative, also must respond to INTRRUPT char This
  363.              * doesn't work with V7.  It should work with LLITOUT, but
  364.              * LLITOUT was broken on the machine I tried it on.
  365.              */
  366.         case 2:         /* Un-raw mode used by sz, sb when -g
  367.                                  * detected */
  368.             if (!did0)
  369.             {
  370.                 ioctl(0, TIOCEXCL, 0);
  371.                 ioctl(0, TIOCGETP, &oldtty);
  372.                 ioctl(0, TIOCGETC, &oldtch);
  373. #ifdef LLITOUT
  374.                 ioctl(0, TIOCLGET, &Locmode);
  375. #endif
  376.             }
  377.             tty = oldtty;
  378.             tch = oldtch;
  379. #ifdef READCHECK
  380.             tch.t_intrc = Zmodem ? -1 : 030;    /* Interrupt char */
  381. #else
  382.             tch.t_intrc = Zmodem ? 03 : 030;    /* Interrupt char */
  383. #endif
  384.             tty.sg_flags |= (ODDP | EVENP | CBREAK);
  385.             tty.sg_flags &= ~(ALLDELAY | CRMOD | ECHO | LCASE);
  386.             ioctl(0, TIOCSETP, &tty);
  387.             ioctl(0, TIOCSETC, &tch);
  388. #ifdef LLITOUT
  389.             ioctl(0, TIOCLBIS, &Locbit);
  390. #endif
  391.             bibi(99);            /* un-raw doesn't work w/o lit out */
  392.             did0 = TRUE;
  393.             return OK;
  394.         case 1:
  395.         case 3:
  396.             if (!did0)
  397.             {
  398.                 ioctl(0, TIOCEXCL, 0);
  399.                 ioctl(0, TIOCGETP, &oldtty);
  400.                 ioctl(0, TIOCGETC, &oldtch);
  401. #ifdef LLITOUT
  402.                 ioctl(0, TIOCLGET, &Locmode);
  403. #endif
  404.             }
  405.             tty = oldtty;
  406.             tty.sg_flags |= (RAW | TANDEM);
  407.             tty.sg_flags &= ~ECHO;
  408.             ioctl(0, TIOCSETP, &tty);
  409.             did0 = TRUE;
  410.             Effbaud = Baudrate = getspeed(tty.sg_ospeed);
  411.             return OK;
  412. #endif
  413.         case 0:
  414.             if (!did0)
  415.                 return ERROR;
  416. #ifdef USG
  417.             (void) ioctl(0, TCSBRK, 1); /* Wait for output to drain */
  418.             (void) ioctl(0, TCFLSH, 1); /* Flush input queue */
  419.             (void) ioctl(0, TCSETAW, &oldtty);    /* Restore modes */
  420.             (void) ioctl(0, TCXONC, 1); /* Restart output */
  421. #endif
  422. #ifdef V7
  423.             ioctl(0, TIOCSETP, &oldtty);
  424.             ioctl(0, TIOCSETC, &oldtch);
  425.             ioctl(0, TIOCNXCL, 0);
  426. #ifdef LLITOUT
  427.             ioctl(0, TIOCLSET, &Locmode);
  428. #endif
  429. #endif
  430.  
  431.             return OK;
  432.         default:
  433.             return ERROR;
  434. #endif    /* endof ifdef __TOWNS__ */
  435.     }
  436. }
  437.  
  438. void    sendbrk(void)
  439. {
  440. #ifdef    __TOWNS__
  441.     RS_breakOut( RsPort, 50 );
  442. #else
  443. #ifdef V7
  444. #ifdef TIOCSBRK
  445. #define CANBREAK
  446.     sleep(1);
  447.     ioctl(0, TIOCSBRK, 0);
  448.     sleep(1);
  449.     ioctl(0, TIOCCBRK, 0);
  450. #endif
  451. #endif
  452. #ifdef USG
  453. #define CANBREAK
  454.     ioctl(0, TCSBRK, 0);
  455. #endif
  456. #endif
  457. }
  458.  
  459. /* End of rbsb.c */
  460.